'''
单例模式：确保环境中只有一个类的实例。（若a = Demo(), b = Demo(), 则 a is b 为 True）

利用java语法更好理解：
既是私有化构造器，不让外部对象使用new 创建一个新的实例。
python：
本质上是，对于单例模式中，新创建的实例，可以理解为不是真正意义上的创建（分配独立的地址空间），而只是对单例类实例的引用。

创建方法：
1、使用__new__()创建单例模式。
2、使用装饰器创建单例模式。
'''


class SingletonNew(object):
    '''
    使用__new__()
    相当于使用构造器创建实例
    '''
    def __new__(cls, *args, **kwargs):  # 类方法，非实例方法
        if not hasattr(cls, 'your_instance'):
            cls.your_instance = super().__new__(cls, *args, **kwargs)
        
        return cls.your_instance
 

def singletonDecorator(_cls):
    '''
    使用函数装饰器（Decorator）
    '''
    instance = {}

    def wrapper(*args, **kwargs):
        if _cls not in instance:
            instance[_cls] = _cls(*args, **kwargs)
        
        return instance[_cls]

    return wrapper

@singletonDecorator
class testSingleton(object):
    pass


class SingletonDecorator(object):
    '''
    使用类装饰器（Decorator）
    只要会写类装饰器，看了函数装饰器就会写类的
    '''
    pass


if __name__ == "__main__":
    new_1 = SingletonNew()
    new_2 = SingletonNew()
    print('new_1: %s' % new_1)
    print('new_2: %s' % new_2)
    print('new_1 is new_2: %s' % (new_1 is new_2))

    dec_1 = testSingleton()
    dec_2 = testSingleton()
    print('dec_1: %s' % dec_1)
    print('dec_2: %s' % dec_2)
    print('dec_1 is dec_2: %s' % (dec_1 is dec_2))
